package io.elegant.widgets

import android.text.InputType
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import com.google.protobuf.Any
import io.elegant.sessions.BaseSession
import io.elegant.toAny
import io.elegant.toBoolValue
import io.elegant.toStringValueOrNull
import kotlinx.coroutines.CoroutineScope

class EditorWidget<T: View>(
    private val session: BaseSession,
    group: ViewGroup,
    cs: CoroutineScope
): BaseTextWidget<T>(session, group, cs) {
    override fun onReceive(name: String, sessionId: Long, futureId: Long, vararg argv: Any): Boolean {
        if (when (name) {
                "getHint" -> getHint(sessionId, futureId)
                "setHint" -> setHint(*argv)
                "isInputPhone" -> isInputPhone(sessionId, futureId)
                "setInputPhone" -> setInputPhone(*argv)
                "isInputNumber" -> isInputNumber(sessionId, futureId)
                "setInputNumber" -> setInputNumber(*argv)
                else -> null
            } == null)
            return super.onReceive(name, sessionId, futureId, *argv)
        return true
    }
    private fun getHint(sessionId: Long, futureId: Long) {
        val hint = (view as EditText?)?.hint?.toString()
        onGetHint(hint.toAny(), sessionId, futureId)
    }
    private fun onGetHint(hint: Any, sessionId: Long, futureId: Long) = session.apply {
        sendAction("onGetHint", sessionId, futureId, hint)
    }
    private fun setHint(vararg argv: Any) {
        (view as EditText?)?.setHint(argv[0].toStringValueOrNull())
    }
    private fun isInputPhone(sessionId: Long, futureId: Long) {
        val type = (view as EditText?)?.inputType ?: InputType.TYPE_NULL
        val isPhone = type and InputType.TYPE_CLASS_PHONE == InputType.TYPE_CLASS_PHONE
        onIsInputPhone(isPhone.toAny(), sessionId, futureId)
    }
    private fun onIsInputPhone(inputPhone: Any, sessionId: Long, futureId: Long) = session.apply {
        sendAction("onIsInputPhone", sessionId, futureId, inputPhone)
    }
    private fun setInputPhone(vararg argv: Any) = (view as EditText?)?.let {
        it.inputType = if (argv[0].toBoolValue())
            it.inputType or InputType.TYPE_CLASS_PHONE
        else if (it.inputType and InputType.TYPE_CLASS_PHONE == InputType.TYPE_CLASS_PHONE)
            it.inputType xor InputType.TYPE_CLASS_PHONE
        else it.inputType
    }
    private fun isInputNumber(sessionId: Long, futureId: Long) {
        val type = (view as EditText?)?.inputType ?: InputType.TYPE_NULL
        val isNumber = type and InputType.TYPE_CLASS_NUMBER == InputType.TYPE_CLASS_NUMBER
        onIsInputNumber(isNumber.toAny(), sessionId, futureId)
    }
    private fun onIsInputNumber(inputNumber: Any, sessionId: Long, futureId: Long) = session.apply {
        sendAction("onIsInputNumber", sessionId, futureId, inputNumber)
    }
    private fun setInputNumber(vararg argv: Any) = (view as EditText?)?.let {
        it.inputType = if (argv[0].toBoolValue())
            it.inputType or InputType.TYPE_CLASS_NUMBER
        else if (it.inputType and InputType.TYPE_CLASS_NUMBER == InputType.TYPE_CLASS_NUMBER)
            it.inputType xor InputType.TYPE_CLASS_NUMBER
        else it.inputType
    }
}